home *** CD-ROM | disk | FTP | other *** search
- Path: mayne.ugrad.cs.ubc.ca!not-for-mail
- From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
- Newsgroups: comp.lang.c
- Subject: Re: String assignments, please help (beginner)
- Date: 9 Apr 1996 11:14:39 -0700
- Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
- Message-ID: <4ke9efINNnv@mayne.ugrad.cs.ubc.ca>
- References: <4ke05g$27q@soap.news.pipex.net>
- NNTP-Posting-Host: mayne.ugrad.cs.ubc.ca
-
- In article <4ke05g$27q@soap.news.pipex.net>, Tone <tone@dial.pipex.com> wrote:
- >I've just been learning C for the last few weeks and have come across
- >a problem with assigning strings, which I will detail below.
- >(Sorry the posting is so long, I'm just trying to make sure you know
- >exactly what my problem is):
- >
- >I was originally informed that the following was valid:
- >
- > char string1[30];
- > string1 = "Test string";
-
- Nope. Whoever told you likely believed that arrays are pointers, which is
- buffoonery.
-
- >This gave me an error on the second line although when declaring I am
- >able to use:
- >
- > char string1[30] = "Test string";
-
- That's because it's not an assignment. It is an initializer. An initializer is
- a special syntactic unit that is part of a declaration. C allows string
- literals to act as initializers for character arrays. Assingments are
- statements, but initializers don't necessarily generate code (when they are
- static).
-
- >I have then read up and found the following info elsewhere (quote):
- >
- > a = "This is a string.";
- > is only possible if a is a char pointer.
-
- Yes. The value of a string literal expression is a pointer to an unnamed piece
- of storage which houses a string. This pointer may be assigned to a char *
- type. There is one exception to this. If you initialize a static char array
- with a string literal, no unnamed storage is necessarily created. Instead, the
- static array is created such that it initially contains the given data. (At
- least this is how it is often _implemented_).
-
-
- >so I arrived at the following:
- >
- > char *string1[30];
- > *string1 = "Test string";
- >
- >This compiles okay and gives the desired result in the small program I
- >was writing.
-
- That is incorrect. The expression "string1" refers to an array object, but
- produces a value that is a pointer to the first element according to the
- special array semantics of C. When you write *string1 the effect is the same as
- though you had written *(&string1[0]). This expression is an lvalue that
- refers to a char object by dereferencing string1[0] pointer. Not only is this
- not assignment compatible with "Test string", but it deferences a pointer that
- has not been initialized.
-
- >However, I have since found the following information (quote):
- >
- > int *c;
- > *c = 4;
-
- It is undefined behavior because c is not initialized.
-
- > can and probably will give some unexpected and unwelcome results!
- > As the value of c is random, the memory-address to which 4 is
- > assigned is random, too. This means that you could change basically
- > any location in the memory, including machine code.
-
- This rationale should be taken with a grain of salt. The truth is that anything
- can happen, based on what the implementation does with such undefined behavior.
-
- >I am assuming that these "unexpected results" mentioned above will
- >also apply to the code I have written.
-
- Well, not exactly. The pointer to the "Test string" literal will probably be
- converted to an integer according to some implementation-defined mapping, and
- then forced into a char.
-
- >The only other way I know of assigning a string is to create a loop
- >(e.g. a "for" loop) and assign each character of the string
- >individually and manually add the '\0' at the end. This seems
- >extremely laborious and I'm sure it can't be the best way. (Also it
- >may give similar "unexpected results"?)
-
- You could do:
-
- char *string1[30];
- string1[0] = "Test string";
- string1[1] = "Another test string";
-
- and so forth.
-
-
- You assign to a string using the standard string functions. If you know that
- the destination operand has enough storage, you can use:
-
- strcpy(dest, source);
-
- Source can be a string literal:
-
- char mystring[50];
-
- strcpy(mystring, "Hello, world!");
-
- When you are not sure how long the source string is, you use strncpy(), which
- takes an additional count argument. The nasty thing is that strncpy() will not
- append a null character to the destination, but copy characters right up to the
- end. So you have a few possibilities:
-
- 1. Store zeros into the destination, then specify a size that is one
- less than the actual size:
-
- char mystring[50];
-
- memset(mystring, 0, sizeof(mystring)); /* store zeros */
-
- strncpy(mystring, mystery_string, sizeof(mystring));
-
- 2. Store a single zero to the last position before or after doing the
- copy:
-
-
- char mystring[50];
-
- strncpy(mystring, mystery_string, sizeof(mystring) - 1);
-
- mystring[sizeof(mystring)-1] = 0;
-
- It would be nice if strncpy() did this for you, wouldn't it? But it's
- standardized to work a certain way.
- --
-
-